package com.spark.lola.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.spark.lola.entity.SupplierToken;
import com.spark.lola.entity.sup.AccountInfo;
import com.spark.lola.request.RegisterRequest;
import com.spark.lola.service.sup.IAccountInfoService;
import com.spark.lola.support.api.constant.ApiConstants;
import com.spark.lola.support.api.entity.TokenUser;
import com.spark.lola.support.api.service.JwtService;
import com.spark.lola.support.common.constant.CommonConstant;
import com.spark.lola.support.common.util.ResponseBean;
import com.spark.lola.support.core.param.LoginRequest;
import com.spark.lola.support.mvc.util.ClientUtils;
import com.spark.lola.support.wms.constant.RedisPrefix;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;

/**
 * 授权 登录/退出
 * @Author: DengYeJun
 * @Date: 2019/12/31 0031 19:56
 */
@RestController
@RequestMapping(value = "/api/auth", produces = "application/json;charset=utf-8")
@Api(value = "/api/auth", tags = "授权")
public class AuthController {
    private static final Logger logger = LoggerFactory.getLogger(AuthController.class);

    @Autowired
    private JwtService jwtService;
    @Autowired
    private IAccountInfoService accountInfoService;
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    private RedisTemplate<String,String> systemRedis;

    /**
     * 用户登录
     */
    @ApiOperation(value = "登录")
    @Transactional(rollbackFor = Exception.class)
    @RequestMapping(value = "/login",method = RequestMethod.POST, consumes = "application/json;charset=UTF-8")
    public ResponseBean login(@RequestBody LoginRequest request,HttpServletRequest httpServletRequest) throws Exception {

        logger.info("===用户【{}】尝试登录===START===", request.getUsername());
        QueryWrapper<AccountInfo> query = new QueryWrapper<>();
        query.eq("username", request.getUsername());
        query.or().eq("mobile", request.getUsername());
        AccountInfo accountInfo = null;
        int count = accountInfoService.count(query);
        if (count == 0) {
            if(!StringUtils.isEmpty(request.getPassword())){
                return ResponseBean.error("用户不存在!");
            }
            if(StringUtils.isEmpty(request.getCode())) {
                return ResponseBean.error("请输入验证码!");
            }
            logger.info("===用户不存在尝试注册...");
            RegisterRequest registerRequest =new RegisterRequest();
            BeanUtils.copyProperties(request,registerRequest);
            registerRequest.setMobile(request.getUsername());
            accountInfo = accountInfoService.register(registerRequest);
        }
        else{
            accountInfo = accountInfoService.list(query).get(0);
            if(accountInfo.getUsed().equals(CommonConstant.N)){
                return ResponseBean.error("当前用户已禁用,请联系客服人员!");
            }
            if(!StringUtils.isEmpty(request.getPassword())) {
                // 密码登录
                if (!bCryptPasswordEncoder.matches(request.getPassword(),accountInfo.getPassword())) {
                    return ResponseBean.error("密码不正确!");
                }
            }
            if(!StringUtils.isEmpty(request.getCode())){
                // 短线验证码登录
                String smsKey = RedisPrefix.REGISTER_CODE+accountInfo.getMobile();
                if(!systemRedis.hasKey(smsKey)){
                    return ResponseBean.error("验证码已过期,请重新获取验证码!");
                }
                String code = systemRedis.opsForValue().get(smsKey);
                if(!code.equals(request.getCode())){
                    return ResponseBean.error("验证码不正确!");
                }else{
                    systemRedis.delete(smsKey);
                }
            }
        }
        String token = createToken(accountInfo);
        logger.info("===用户【{}】Token【{}】", request.getUsername(), token);
        String ip = ClientUtils.getClientIPAddress(httpServletRequest);
        accountInfo.setLoginCount(accountInfo.getLoginCount()+1);
        accountInfo.setLastTime(new Date());
        accountInfo.setLastIp(ip);
        accountInfoService.updateById(accountInfo);
        logger.info("===用户【{}】尝试登录===END===", request.getUsername());

        return ResponseBean.success(token);
    }

    @ApiOperation(value = "刷新令牌")
    @RequestMapping(value = "/refresh-token",method = RequestMethod.POST)
    public ResponseBean refreshToken(@SessionAttribute SupplierToken tokenUser){
        AccountInfo accountInfo = accountInfoService.getById(tokenUser.getMemberId());
        String token = createToken(accountInfo);
        logger.info("===用户【{}】刷新Token【{}】", tokenUser.getUsername(), token);
        return ResponseBean.success(token);
    }

    public String createToken(AccountInfo accountInfo){
        SupplierToken tokenUser = new SupplierToken();
        tokenUser.setMemberId(accountInfo.getId());
        tokenUser.setUsername(accountInfo.getUsername());
        tokenUser.setCertificationStatus(accountInfo.getCertificationStatus());
        tokenUser.setSupplierId(accountInfo.getSupplierId());
        // 写入会话缓存
        String token = jwtService.createToken(JSON.toJSONString(tokenUser));
        return  token;
    }

}
